#!/usr/bin/env -S node -r ./livescript-transform-implicit-async/register


require! {
  \fs-extra : fs
  \isomorphic-git : git
}

require! <[
  chalk
  path
  ./log
  ./CONST.ls
  ./Tmpdir.ls
]>


git.plugins.set('fs', require('fs'))

do !~>
  _pre = new Date()

  git.plugins.set(\emitter, {
    emit:(event, msg)!->
      if event == \message
        now = new Date()
        if now - _pre > 3000
          console.log chalk.gray msg
          _pre := now
  })


class Git
  (@dir)->

  clone : (url, ref)!->
    dir = @dir
    if not await fs.pathExists(dir)
      await git.clone {
       depth:1
       url
       dir
       ref
      }

  version-li : ->
    dir = @dir
    semver = require \semver
    li = []
    for i in await git.listTags(
      {
        dir
      }
    )
      if i.charAt(0) == 'v'
        v = i.slice(1)
        if semver.valid(v)
          li.push v
    li.sort (a,b)~>
      if semver.lt(a,b) then 1 else -1
    li

  version-max : ->
    dir = @dir
    semver = require \semver
    for i in await git.listTags(
      {
        dir
      }
    )
      if i.charAt(0) == 'v'
        v = i.slice(1)
        if semver.valid(v)
          if version-max
            if semver.gt(v, version-max)
              version-max = v
          else
            version-max = v
    version-max

  fetch : ->
    git.fetch(
      {
        dir: @dir
        tags:true
      }
    )

  checkout : (ref)->
    git.checkout {
      dir: @dir
      ref
    }

  remote-origin : ->
    for i in await git.listRemotes {dir:@dir}
      if i.remote == \origin
        return i.url

  resolve-ref: (ref)->
    git.resolve-ref {
      dir:@dir
      ref
    }

  read-object: (oid)->
    git.read-object {
      dir:@dir
      oid
    }

  expand-ref: (ref)->
    git.expand-ref {
      ref
      dir:@dir
    }

  update-log:->
    now = await @resolve-ref \HEAD
    li = []
    for i in await @version-li!
      hash = await @resolve-ref(\v + i)
      if hash == now
        break
      o = (await @read-object hash).object
      {timestamp, timezoneOffset} = o.committer or o.tagger
      li.push [
        new Date((timestamp - timezoneOffset*60)*1000).toISOString!.slice(0,10)
        o.message
      ]
    li

  npm-install : (url)->
    dir = @dir

    n = 0
    for p in <[
      .git/config
      .git/HEAD
    ]>
      n += (await fs.exists(path.join(dir,p))) - 1

    if n
      await fs.remove(dir)

      tmpdir = Tmpdir!

      await git.clone {
       url
       depth:1
       dir:tmpdir
       ref:\v
      }

      v = await @version-max tmpdir

      if v
        await git.checkout {
          dir:tmpdir
          ref:'v'+v
        }

      await require(\./npm-install.ls) tmpdir
      await fs.move tmpdir,dir
      return true
    else
      if not await fs.exists(
        path.join(dir, \node_modules)
      )
        await require(\./npm-install.ls) dir



module.exports = (dir)~>
  new Git dir

if require.main == module
  do ~>
    g = module.exports __dirname
    for i in await g.update-log!
      console.log i


#git.reset = ({ref, commit, dir})->
#  if not ref
#    ref = await git.currentBranch({dir})

#  git-dir = path.join dir, '.git'

#  await fs.writeFile(
#    path.join git-dir, 'refs/heads', ref
#    commit
#  )
#  await fs.unlink path.join git-dir, \index
#  await git.checkout {
#    dir
#    ref
#  }

#  #   # tag 的 currentBranch 是 undefined
#  #   if await git.currentBranch({dir})


